/*
 * Copyright 2018-2021 guerlab.net and other contributors.
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.guerlab.smart.pay.service.cron;

import net.guerlab.commons.collection.CollectionUtil;
import net.guerlab.smart.pay.core.enums.PayStatus;
import net.guerlab.smart.pay.core.searchparams.PayOrderSearchParams;
import net.guerlab.smart.pay.service.entity.PayOrder;
import net.guerlab.smart.pay.service.service.PayOrderService;
import net.guerlab.smart.pay.stream.binders.MultiPayOrderStatusChangeSenderChannel;
import net.guerlab.smart.pay.stream.domain.MultiPayOrderStatus;
import net.guerlab.smart.platform.stream.utils.MessageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Collection;

/**
 * 支付订单-计划任务
 *
 * @author guer
 */
@Component
@EnableBinding(MultiPayOrderStatusChangeSenderChannel.class)
public class PayOrderCron {

    private PayOrderService payOrderService;

    private MultiPayOrderStatusChangeSenderChannel statusChangeSender;

    @Autowired
    public void setPayOrderService(PayOrderService payOrderService) {
        this.payOrderService = payOrderService;
    }

    @Autowired
    public void setStatusChangeSender(MultiPayOrderStatusChangeSenderChannel statusChangeSender) {
        this.statusChangeSender = statusChangeSender;
    }

    /**
     * 每1分钟关闭支付超时的订单
     */
    @Scheduled(cron = "0 * * * * ?")
    void closeWithPayTimeOut() {
        LocalDateTime now = LocalDateTime.now();
        PayOrderSearchParams selectSearchParams = new PayOrderSearchParams();
        selectSearchParams.setPayStatus(PayStatus.WAIT_PAY);
        selectSearchParams.setPayTimeoutTimeEndWith(now);

        Collection<PayOrder> payOrders = payOrderService.selectAll(selectSearchParams);

        Collection<Long> ids = CollectionUtil.toList(payOrders, PayOrder::getPayOrderId);

        if (ids.isEmpty()) {
            return;
        }

        PayOrderSearchParams updateSearchParams = new PayOrderSearchParams();
        updateSearchParams.setPayOrderIds(ids);

        PayOrder updateInfo = new PayOrder();
        updateInfo.setPayStatus(PayStatus.TIMEOUT);
        updateInfo.setPayCancelTime(now);

        if (payOrderService.update(updateInfo, updateSearchParams)) {
            MultiPayOrderStatus multiPayOrderStatus = new MultiPayOrderStatus();
            multiPayOrderStatus.setChangeTime(now);
            multiPayOrderStatus.setPayOrderIds(ids);
            multiPayOrderStatus.setPayStatus(PayStatus.TIMEOUT);

            MessageUtils.send(statusChangeSender.output(), multiPayOrderStatus);
        }
    }
}
